package fun.tan90.easy.binlog.worker.config;

import com.github.benmanes.caffeine.cache.Caffeine;
import com.github.benmanes.caffeine.cache.LoadingCache;
import fun.tan90.easy.binlog.base.strategy.AbstractStrategyChoose;
import fun.tan90.easy.binlog.plugin.common.model.BinlogOutputRule;
import fun.tan90.easy.binlog.plugin.common.model.OutputParam;
import fun.tan90.easy.binlog.plugin.common.model.TableMeta;
import fun.tan90.easy.binlog.plugin.common.model.TableMetaParam;
import fun.tan90.easy.binlog.worker.client.EbWorker;
import fun.tan90.easy.binlog.worker.config.cache.BinlogColumnsCacheLoader;
import fun.tan90.easy.binlog.worker.config.cache.OutputParamCacheLoader;
import fun.tan90.easy.binlog.worker.config.cache.OutputRuleCacheLoader;
import fun.tan90.easy.binlog.worker.property.EasyBinlogWorkerProperties;
import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;

import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;

/**
 * description TODO
 * company 铁人科技
 *
 * @author 陈浩杰
 * @date 2023/7/13 8:50
 */
@Slf4j
@Configuration
@Import(cn.hutool.extra.spring.SpringUtil.class)
@EnableConfigurationProperties(EasyBinlogWorkerProperties.class)
public class EasyBinlogPlusWorkerAutoConfiguration {

    /**
     * 策略模式选择器
     */
    @Bean
    public AbstractStrategyChoose abstractStrategyChoose() {
        return new AbstractStrategyChoose();
    }

    @Bean
    public BinlogColumnsCacheLoader binlogColumnsCacheLoader() {
        return new BinlogColumnsCacheLoader();
    }

    @Bean
    public LoadingCache<TableMetaParam, TableMeta> binlogColumnsCache(BinlogColumnsCacheLoader binlogColumnsCacheLoader) {
        return Caffeine.newBuilder()
                .maximumSize(10_000)
                .expireAfterAccess(1, TimeUnit.DAYS)
                .recordStats()
                .build(binlogColumnsCacheLoader);
    }

    @Bean
    public OutputParamCacheLoader outputParamCacheLoader(EbWorker ebWorker) {
        return new OutputParamCacheLoader(ebWorker);
    }

    @Bean
    public LoadingCache<String, OutputParam> outputParamCache(OutputParamCacheLoader outputParamCacheLoader) {
        return Caffeine.newBuilder()
                .maximumSize(10_000)
                .expireAfterAccess(1, TimeUnit.DAYS)
                .recordStats()
                .build(outputParamCacheLoader);
    }

    @Bean
    public OutputRuleCacheLoader outputRuleCacheLoader(EbWorker ebWorker) {
        return new OutputRuleCacheLoader(ebWorker);
    }

    @Bean
    public LoadingCache<String, Map<String, List<BinlogOutputRule>>> outputRuleCache(OutputRuleCacheLoader outputRuleCacheLoader) {
        return Caffeine.newBuilder()
                .maximumSize(10_000)
                .expireAfterAccess(1, TimeUnit.DAYS)
                .recordStats()
                .build(outputRuleCacheLoader);
    }
}